from BlockChain.分模块实现简单区块链.Block_dada import InvalidBlock, Block
from BlockChain.分模块实现简单区块链.Message import DaDaMessage, InvalidMessage
from BlockChain.分模块实现简单区块链.Transaction import Transaction


class Dada_BlockCoin:  # 区块链
    def __init__(self):  # 初始化
        self.blockList = []

    def add_block(self, block):  # 增加区块
        if (len(self.blockList) > 0):
            block.prev_hash = self.blockList[-1].hash  # 区块链的哈希
        block.seal()  # 密封
        block.validate()  # 校验
        self.blockList.append(block)  # 增加区块

    def validate(self):  # 校验
        for i, block in enumerate(self.blockList):
            try:
                block.validate()
            except InvalidBlock as e:
                raise InvalidBlockCoin("区块校验错误，区块索引{}".format(i))
            except InvalidMessage as e:
                print(e)

    def __repr__(self):  # 字符串格式化
        return "Dada_BlockCoin : {}".format(len(self.blockList))  # 获取长度


class InvalidBlockCoin(Exception):  # blockCoin异常
    def __init__(self, *arg, **kargs):
        Exception.__init__(self, *arg, **kargs)


if __name__ == '__main__':
    try:
        t1 = Transaction("x", "y1", 1)
        t2 = Transaction("x", "y2", 2)
        t3 = Transaction("x", "y3", 3)
        t4 = Transaction("x", "y4", 4)
        t5 = Transaction("x", "y5", 5)
        t6 = Transaction("x", "y6", 6)

        m1 = DaDaMessage(t1)  # 交易记录
        m2 = DaDaMessage(t2)
        m3 = DaDaMessage(t3)
        m4 = DaDaMessage(t4)
        m5 = DaDaMessage(t5)
        m6 = DaDaMessage(t6)

        # 三个区块
        yin1 = Block(m1, m2)
        yin1.seal()

        yin2 = Block(m3, m4)
        yin2.seal()

        yin3 = Block(m5, m6)
        yin3.seal()

        # 篡改区块
        yin3.messageList.append(m1)

        myBlockCoin = Dada_BlockCoin()  # 区块链
        myBlockCoin.add_block(yin1)
        myBlockCoin.add_block(yin2)
        myBlockCoin.add_block(yin3)
        myBlockCoin.validate()
        print(myBlockCoin)
    except Exception as e:
        print(e)

